import { SortableEvent } from 'sortablejs';
import { VNodeData } from 'vue';
import { PanelDataProvider, PanelLayoutProvider } from '../../interface';
import { LayoutItemBasicComponent } from '../layout-item-basic-component/layout-item-basic-component';

/**
 * 使用 Sortable 组件，进行拖拽排序基础扩展
 *
 * @author chitanda
 * @date 2022-02-17 17:02:53
 * @export
 * @class SortableLayoutBasicComponent
 * @extends {LayoutItemBasicComponent}
 */
export class SortableLayoutBasicComponent extends LayoutItemBasicComponent {
  /**
   * sortable 组件参数
   *
   * @author chitanda
   * @date 2022-02-17 17:02:25
   */
  sortableOptions = {
    group: {
      name: 'x',
      pull: true,
      put: true,
    },
    swapThreshold: 0.9,
    invertSwap: true,
    animation: 150,
  };

  /**
   * sortable 组件 vue 渲染参数
   *
   * @author chitanda
   * @date 2022-02-17 17:02:33
   * @type {VNodeData}
   */
  vNodeData: VNodeData = {
    props: {
      options: this.sortableOptions,
    },
    attrs: {
      group: this.sortableOptions.group,
    },
  };

  created(): void {
    super.created();
    this.vNodeData.on = {
      start: this.start.bind(this),
      add: this.add.bind(this),
      remove: this.remove.bind(this),
      update: this.update.bind(this),
      end: this.end.bind(this),
    };
  }

  /**
   * 拖拽开始
   *
   * @author chitanda
   * @date 2022-02-18 14:02:25
   * @param {SortableEvent} evt
   */
  start(evt: SortableEvent): void {
    this.panel.dragging.from = this.data;
    const data = this.children[evt.oldIndex!];
    this.panel.dragging.item = data;
  }

  /**
   * 新增项
   *
   * @author chitanda
   * @date 2022-02-18 14:02:32
   * @param {SortableEvent} evt
   */
  async add(evt: SortableEvent): Promise<void> {
    console.log('add');
    this.panel.dragging.to = this.data;
    this.removeNode(evt.item);
    let data: PanelDataProvider | null = null;
    if (evt.pullMode === 'clone') {
      const type = evt.item.getAttribute('provider-type') as string;
      const provider = this.panel.getProvider(type) as PanelLayoutProvider;
      data = await provider.createItem(this.data);
    } else if (this.panel.dragging.item) {
      data = this.panel.dragging.item;
      const provider = this.panel.getProvider(data.type) as PanelLayoutProvider;
      await provider.moveItem(this.panel.dragging.from!, this.panel.dragging.to, data);
    }
    if (data) {
      this.children.splice(evt.newIndex!, 0, data);
      this.$forceUpdate();
    }
  }

  /**
   * 删除项
   *
   * @author chitanda
   * @date 2022-02-18 14:02:38
   * @param {SortableEvent} evt
   */
  async remove(evt: SortableEvent): Promise<void> {
    console.log('remove');
    this.children.splice(evt.oldIndex!, 1);
    this.$forceUpdate();
  }

  /**
   * 更新项
   *
   * @author chitanda
   * @date 2022-02-18 14:02:43
   * @param {SortableEvent} evt
   */
  async update(evt: SortableEvent): Promise<void> {
    console.log('update');
    this.panel.dragging.to = this.data;
    const data = this.children[evt.oldIndex!];
    const provider = this.panel.getProvider(data.type) as PanelLayoutProvider;
    await provider.moveItem(this.panel.dragging.from!, this.panel.dragging.to, data);
    this.children.splice(evt.oldIndex!, 1);
    this.children.splice(evt.newIndex!, 0, data);
    this.$forceUpdate();
  }

  /**
   * 结束拖拽
   *
   * @author chitanda
   * @date 2022-02-18 14:02:49
   */
  end(): void {
    this.panel.draggingReset();
  }

  /**
   * 删除多余呈现的 DOM 节点
   *
   * @author chitanda
   * @date 2022-02-18 14:02:01
   * @param {Element} node
   */
  removeNode(node: Element): void {
    if (node.parentElement !== null) {
      node.parentElement.removeChild(node);
    }
  }
}
